package cn.com.b2office.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import cn.com.b2office.dao.AccountActivityDao;
import cn.com.b2office.dao.CountyDao;
import cn.com.b2office.dao.DeliveryDao;
import cn.com.b2office.dao.DictDao;
import cn.com.b2office.dao.ItemDao;
import cn.com.b2office.dao.MemberDao;
import cn.com.b2office.dao.OrderDao;
import cn.com.b2office.dao.PaymentModeDao;
import cn.com.b2office.dao.ShopDao;
import cn.com.b2office.dao.SpecialCategoryDao;
import cn.com.b2office.domain.AccountActivity;
import cn.com.b2office.domain.Cart;
import cn.com.b2office.domain.CartItem;
import cn.com.b2office.domain.City;
import cn.com.b2office.domain.County;
import cn.com.b2office.domain.DeliveryMode;
import cn.com.b2office.domain.District;
import cn.com.b2office.domain.Item;
import cn.com.b2office.domain.MemberAddress;
import cn.com.b2office.domain.Order;
import cn.com.b2office.domain.OrderItem;
import cn.com.b2office.domain.PaymentMode;
import cn.com.b2office.domain.SendDate;
import cn.com.b2office.domain.Shop;
import cn.com.b2office.service.OrderService;

public class OrderServiceImpl implements OrderService {

	private ItemDao itemDao = null;

	private DeliveryDao deliveryDao = null;

	private SpecialCategoryDao specialCategoryDao = null;

	private OrderDao orderDao = null;

	private PaymentModeDao paymentModeDao = null;

	private DictDao dictDao = null;

	private MemberDao memberDao = null;

	private CountyDao countyDao = null;

	private ShopDao shopDao = null;

	private AccountActivityDao accountActivityDao = null;

	public void appCancelOrder(String orderId) {
		Order order = orderDao.getOrder(orderId);
		if (order == null)
			throw new RuntimeException("order is null. orderId=" + orderId);
		if (order.getOrderStatus() != -1)
			throw new IllegalStateException("order status="
					+ order.getOrderStatus() + ". orderId=" + orderId);
		order.setCancelApp(1);
		orderDao.updateOrder(order);
	}

	/**
	 * 除尚未生成实体ID之外，其余属性已基本配置完成（尚需检验，如地址完整，电话完整之类检查）
	 */
	public List<Order> buildOrders(Cart cart) {
		PaymentMode payMode = paymentModeDao.getPaymentMode(cart.getPayMode());
		DeliveryMode deliveryMode = deliveryDao.getDeliveryMode(cart
				.getDeliveryMode());
		MemberAddress address = null;
		County county = null;
		District district = null;
		City city = null;
		Shop shop = null;
		if (cart.getAddressId() != null) {
			address = memberDao.getAddress(cart.getAddressId());
			county = countyDao.getCounty(address.getCountyid());
			district = countyDao.getDistrict(county.getDistrict());
			city = countyDao.getCity(district.getCityid());
			shop = shopDao.getManageShop(county.getIdno());
		}

		Date orderDate = new Date(cart.getShoppingTime());
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();

		List<Order> orders = new ArrayList<Order>(cart.getCartItems().size());
		double totalAmt = 0.0;
		int cartSize = 0;// 商品个数
		Iterator<SendDate> iterator = cart.getCartItems().keySet().iterator();
		while (iterator.hasNext()) {
			SendDate sendDate = iterator.next();
			Order order = new Order();

			order.setOrderDate(orderDate);
			order.setMemberId(cart.getMemberId());
			order.setReceiveAddrId(cart.getAddressId());
			if (cart.getAddressId() != null) {
				order.setReceiver(address.getCname());
				order.setReceiveDist(district.getDname());
				order.setReceiveCounty(county.getCname());
				order.setCountyId(county.getIdno());
				order.setReceiveAddress(address.getAddr());
				order.setReceiveZip(address.getZipcode());
				order.setReceiveTel(address.getTel());
				order.setReceiveMobile(address.getMobil());
				order.setReceiveMail(address.getEmail());

				if (shop != null)
					order.setShopId(shop.getIdno());
			}
			order.setPaymethods(payMode.getCname());
			order.setDeliveryMode(deliveryMode.getCname());
			if (cart.getInvoiced() == 1) {
				order.setInvtitle(cart.getInvoiceTitle());
				order.setInvkind(dictDao.getInvoice(cart.getInvoiceKind())
						.getCname());
			}

			// 该处已失去意义。订单生成之后不会在拆分。所有的订单都是在拆分之后生成。
			order.setCansplit(cart.getSplit());

			calendar.setTime(orderDate);
			calendar.add(Calendar.DAY_OF_YEAR, sendDate.getDays());
			order.setDeliveryTime(df.format(calendar.getTime()) + " "
					+ sendDate.getTime());

			List<CartItem> cartItems = cart.getCartItems().get(sendDate);
			for (CartItem cartItem : cartItems) {
				Item item = itemDao.getItem(cartItem.getItemId());
				OrderItem orderItem = buildOrderItem(item, cartItem.getQty(),
						cartItem.getShape(), cartItem.getComments(), cart
								.getEnableDiscount());
				// orderItem的编号暂时采用cartItem的ID，数据持久化时再进行重新分配
				orderItem.setOrderItemId(String.valueOf(cartItem.getId()));
				// 设置订单里面特殊配送商品
				if (orderItem.isSpecialDeliver()) {
					order.setSpecialDeliver(true);
				}
				cartSize++;
				order.addOrderItem(orderItem);
			}
			totalAmt = totalAmt + order.getB2hamt();
			orders.add(order);
		}

		// 更新购物车的配送费
		cart.setCartSize(cartSize);
		cart.setSum(totalAmt);
		cart.setFreight(deliveryDao.findDeliveryFee(deliveryMode.getIdno(),
				totalAmt).getFee());
		return orders;
	}

	private OrderItem buildOrderItem(Item item, int qty, int shape,
			String comments, int isDiscount) {

		OrderItem orderItem = new OrderItem();
		orderItem.setItem_no(item.getItem_no());
		orderItem.setItem_name(item.getTitles());
		orderItem.setQty(qty);
		orderItem.setUnit(item.getUnit_no());
		orderItem.setB2hprice(item.getB2hprice());
		orderItem.setDeliveryday(item.getDeliverday());

		// orderItem.setRealqty(qty);
		if (item.getUsenewunit() == 1) {// 是否启用新订购单位
			orderItem.setRealunit(item.getNewunit());
			if (item.getUseshape() == 1) {// 采用形状大小分类
				if (shape == OrderItem.BIG_SHAPE) {
					orderItem.setShape("大");
					orderItem.setShapweight(item.getBigqty());
					orderItem.setNewUnitPrice(item.getBigqty()
							* item.getB2hprice());
				} else if (shape == OrderItem.MID_SHAPE) {
					orderItem.setShape("中");
					orderItem.setShapweight(item.getMidqty());
					orderItem.setNewUnitPrice(item.getMidqty()
							* item.getB2hprice());
				} else if (shape == OrderItem.SML_SHAPE) {
					orderItem.setShape("小");
					orderItem.setShapweight(item.getSmlqty());
					orderItem.setNewUnitPrice(item.getSmlqty()
							* item.getB2hprice());
				}
			} else {
				orderItem.setShapweight(item.getMidqty());
				orderItem
						.setNewUnitPrice(item.getMidqty() * item.getB2hprice());
			}

			orderItem.setTotalSum(qty * orderItem.getNewUnitPrice());// 启用新单位后计算金额
		} else {
			orderItem.setTotalSum(orderItem.getQty() * item.getB2hprice());// 没有启用新单位后计算金额
		}

		// 是否启用折扣率
		if (isDiscount == 1) {
			// 折扣率
			orderItem.setDiscountRate(item.getDiscountRate());
			// 总金额乘以折扣率
			orderItem.setTotalSum(orderItem.getTotalSum()
					* orderItem.getDiscountRate());
		} else {
			// 不享受折扣条件则折扣率为1
			orderItem.setDiscountRate(1);
		}

		// 是否需要称重
		orderItem.setStates(item.getNeedweigh() == 1 ? 4 : 0);// 设置订单明细所属的类型：0商品

		// 判断是否是特殊商品（不可延后配送）
		int sortwt = contain(item.getItem_clsno());
		if (sortwt != -1) {
			orderItem.setSpecialDeliver(true);
			orderItem.setSpecialDeliverWt(sortwt);
		}

		// 对于非秤重商品生成订单时： bi_t_item_info.needweigh==0
		// 1.需要把podetail.qty,podetail.realqty赋相同的值
		// 2.如果没有启用新单位bi_t_item_info.usenewunit==0，则podetail.realunit与podetail.unit赋相同的值
		if (item.getNeedweigh() == 0) {
			orderItem.setRealqty(orderItem.getQty());
			if (item.getUsenewunit() == 0)
				orderItem.setRealunit(orderItem.getUnit());
		}

		// 积分相关
		orderItem.setPointrate(item.getPoint_rate());
		// orderItem.setNeedpoint(item.getPoints());
		orderItem.setMakepoint((int) Math.floor(orderItem.getTotalSum()
				* item.getPoint_rate()));// 向下取整
		orderItem.setComments(comments);
		// orderItem.setModifytime(new Date());

		return orderItem;
	}

	private int contain(String categoryId) {
		int sortwt = -1;
		sortwt = specialCategoryDao.isInSpecialCategory(categoryId.substring(0,
				4));
		return sortwt;
	}

	public void cancelOrder(String orderId) {
		Order order = orderDao.getOrder(orderId);
		if (order == null)
			throw new RuntimeException("order is null. orderId=" + orderId);
		if (order.getOrderStatus() != 0)
			throw new IllegalStateException("order status="
					+ order.getOrderStatus() + ". orderId=" + orderId);
		// TODO： 事务包裹
		order.setOrderStatus(-1);
		List<AccountActivity> activities = accountActivityDao
				.findAccountActivities(orderId);
		Date cur = new Date();
		for (AccountActivity act : activities) {
			act.setStatus(-1);
			act.setModifytime(cur);
			accountActivityDao.updateAccountActivity(act);
		}
		orderDao.updateOrder(order);
	}

	/**
	 * 1、检查参数是否正确 2、重新生成主键 3、配送费 3、设置最后修改时间 4、生成帐户活动记录 5、发短信等
	 */
	public void persisteOrder(List<Order> orders,
			List<AccountActivity> activities) {
		// TODO:事务包裹
		for (int i = 0; i < orders.size(); i++) {
			Order order = orders.get(i);
			orderDao.createOrder(order);
			orderDao.createOrderItems(order.getOrderItems());
			accountActivityDao.createAccountActivity(activities.get(i));
		}
	}

	public List<Order> createOrder(Cart cart) {
		Date cur = new Date();
		List<Order> orders = buildOrders(cart);
		List<AccountActivity> activities = new ArrayList<AccountActivity>();
		if (orders == null || orders.isEmpty())
			throw new RuntimeException("orders is null or empty.");
		for (Order order : orders) {
			String orderId = orderDao.createOrderId();
			order.setOrderId(orderId);
			order.setOrderDate(cur);
			order.setModifytime(cur);
			List<OrderItem> orderItems = order.getOrderItems();
			List<String> orderItemIdList = orderDao
					.createOrderItemId(orderItems.size());
			int points = 0;
			for (int i = 0; i < orderItems.size(); i++) {
				OrderItem t = orderItems.get(i);
				t.setModifytime(cur);
				t.setOrderId(order.getOrderId());
				t.setOrderItemId(orderItemIdList.get(i));
				points = points + t.getMakepoint();
			}
			AccountActivity activity = new AccountActivity();
			activity.setActno(accountActivityDao.createAccountActivityId());
			activity.setPono(order.getOrderId());
			activity.setMemberid(order.getMemberId());
			activity.setAmount(0 - order.getB2hamt()); // 发生金额:充值（正数）；消费（负数）；退货（正数）
			activity.setGetpoint(points);
			activity.setActvtype(2);// 1充值；2消费；3退货
			activity.setStatus(0);// 消费状态 0未确认；1确认(生成送货单时赋值)；-1取消
			activity.setModifytime(cur);
			activity.setComments(null);
			activities.add(activity);
		}
		persisteOrder(orders, activities);
		return orders;
	}

	public List<Order> findOrders(String memberId, int firstResult,
			int maxResults) {
		return orderDao.findOrders(memberId, firstResult, maxResults);
	}

	public List<Order> findOrders(String memberId, int orderStatus,
			int firstResult, int maxResults) {

		return orderDao.findOrders(memberId, orderStatus, firstResult,
				maxResults);
	}

	public int getTotalRecordNumByOrderStatus(String memberId, int orderStatus) {

		return orderDao.getTotalRecordNumByOrderStatus(memberId, orderStatus);
	}

	public Order getOrder(String orderId) {
		return orderDao.getOrder(orderId);
	}

	public List<AccountActivity> getOrderAccountActivity(String orderId) {
		return null;
	}

	public List<OrderItem> getOrderItems(String orderId) {
		return orderDao.findOrderItems(orderId);
	}

	public void setDeliveryDao(DeliveryDao deliveryDao) {
		this.deliveryDao = deliveryDao;
	}

	public void setDictDao(DictDao dictDao) {
		this.dictDao = dictDao;
	}

	public void setItemDao(ItemDao itemDao) {
		this.itemDao = itemDao;
	}

	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}

	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}

	public void setPaymentModeDao(PaymentModeDao paymentModeDao) {
		this.paymentModeDao = paymentModeDao;
	}

	public void setSpecialCategoryDao(SpecialCategoryDao specialCategoryDao) {
		this.specialCategoryDao = specialCategoryDao;
	}

	public void setCountyDao(CountyDao countyDao) {
		this.countyDao = countyDao;
	}

	public void setShopDao(ShopDao shopDao) {
		this.shopDao = shopDao;
	}

	public void setAccountActivityDao(AccountActivityDao accountActivityDao) {
		this.accountActivityDao = accountActivityDao;
	}

}
